home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 4 / The Arsenal Files 4 (Arsenal Computer).ISO / ham / sattrk31.tgz / sattrack-3.1.tar / SatTrack / src / sattrack / satcity.c < prev    next >
C/C++ Source or Header  |  1995-03-16  |  13KB  |  381 lines

  1. /******************************************************************************/
  2. /*                                                                            */
  3. /*  Title       : satcity.c                                                   */
  4. /*  Author      : Manfred Bester                                              */
  5. /*  Date        : 17Sep92                                                     */
  6. /*  Last change : 15Mar95                                                     */
  7. /*                                                                            */
  8. /*  Synopsis    : Routines that deal with the city data base.                 */
  9. /*                                                                            */
  10. /*                                                                            */
  11. /*  SatTrack is Copyright (c) 1992, 1993, 1994, 1995 by Manfred Bester.       */
  12. /*  All Rights Reserved.                                                      */
  13. /*                                                                            */
  14. /*  Permission to use, copy, and distribute SatTrack and its documentation    */
  15. /*  in its entirety for educational, research and non-profit purposes,        */
  16. /*  without fee, and without a written agreement is hereby granted, provided  */
  17. /*  that the above copyright notice and the following three paragraphs appear */
  18. /*  in all copies. SatTrack may be modified for personal purposes, but        */
  19. /*  modified versions may NOT be distributed without prior consent of the     */
  20. /*  author.                                                                   */
  21. /*                                                                            */
  22. /*  Permission to incorporate this software into commercial products may be   */
  23. /*  obtained from the author, Dr. Manfred Bester, 1636 M. L. King Jr. Way,    */
  24. /*  Berkeley, CA 94709, USA. Note that distributing SatTrack 'bundled' in     */
  25. /*  with ANY product is considered to be a 'commercial purpose'.              */
  26. /*                                                                            */
  27. /*  IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, */
  28. /*  SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF   */
  29. /*  THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE AUTHOR HAS BEEN ADVISED  */
  30. /*  OF THE POSSIBILITY OF SUCH DAMAGE.                                        */
  31. /*                                                                            */
  32. /*  THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT      */
  33. /*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A   */
  34. /*  PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"      */
  35. /*  BASIS, AND THE AUTHOR HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, */
  36. /*  UPDATES, ENHANCEMENTS, OR MODIFICATIONS.                                  */
  37. /*                                                                            */
  38. /******************************************************************************/
  39.  
  40. #include <stdio.h>
  41. #include <math.h>
  42. #include <string.h>
  43.  
  44. #ifndef STDLIB
  45. #include <stdlib.h>
  46. #endif
  47.  
  48. #include "satglobalsx.h"
  49. #include "sattrack.h"
  50.  
  51. /******************************************************************************/
  52. /*                                                                            */
  53. /* ground track vector segments                                               */
  54. /*                                                                            */
  55. /******************************************************************************/
  56.  
  57. char *gndTrkVector[] = { "N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE",
  58.                          "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW" };
  59.  
  60. /******************************************************************************/
  61. /*                                                                            */
  62. /* getGroundTrack: calculates the distance and direction of the nearest city  */
  63. /*                                                                            */
  64. /******************************************************************************/
  65.  
  66. void getGroundTrack(latSat,lngSat,cityLtd,cityLng,groundTrkDist,
  67.                     groundTrkDir,groundTrkCity)
  68.  
  69. double latSat, lngSat, *cityLtd, *cityLng, *groundTrkDist;
  70. char   *groundTrkDir, *groundTrkCity;
  71.  
  72. {
  73.     double cityVec[3], sspVec[3], distVec[3], northVec[3], eastVec[3];
  74.     double aziX, aziY, azi, alpha, distR, distRad, arg;
  75.     double cosLatSite, sinLatSite, cosLngSite, sinLngSite;
  76.     double cosLatSat, sinLatSat, cosLngSat, sinLngSat;
  77.     double latLimit = ZERO;
  78.     double lngLimit = ZERO;
  79.     int    i, j, dir, cityPointer;
  80.  
  81.     cityPointer = 0;                       /* default setting: the North Pole */
  82.                                            /* (or first entry in cities.dat)  */
  83.  
  84.     cosLatSat = cos(latSat);               /* geodetic latitude and longitude */
  85.     sinLatSat = sin(latSat);
  86.     cosLngSat = cos(lngSat);
  87.     sinLngSat = sin(lngSat);
  88.  
  89.     sspVec[0] = cosLngSat*cosLatSat;
  90.     sspVec[1] = sinLngSat*cosLatSat;
  91.     sspVec[2] = sinLatSat;
  92.  
  93.     distRad   = ONEMEG;
  94.  
  95.     if (fabs(latSat) > 70*CDR)         /* search limits for polar regions     */
  96.     {
  97.         latLimit =  30.1*CDR;
  98.         lngLimit = 360.1*CDR;
  99.     }
  100.  
  101.     if (fabs(latSat) <= 70*CDR)        /* search limits for rest of the world */
  102.     {
  103.         latLimit =  45.0*CDR;
  104.         lngLimit =  45.0*CDR;
  105.     }
  106.  
  107.     if (latSat > 30*CDR && latSat <  50*CDR &&
  108.         lngSat > 70*CDR && lngSat < 130*CDR)
  109.     {
  110.         latLimit =  20.0*CDR;          /* search limits for the United States */
  111.         lngLimit =  20.0*CDR;
  112.     }
  113.  
  114.     for (i = 0; i < numCities; i++)
  115.     {
  116.         if (fabs(latSat - city[i].lat) < latLimit &&
  117.             fabs(lngSat - city[i].lng) < lngLimit)
  118.         {
  119.             distVec[0] = city[i].X - sspVec[0];
  120.             distVec[1] = city[i].Y - sspVec[1];
  121.             distVec[2] = city[i].Z - sspVec[2];
  122.  
  123.             distR = absol(distVec);
  124.  
  125.             if (distR < distRad - ONEPPM)
  126.             {
  127.                 distRad     = distR;
  128.                 cityPointer = i;
  129.             }
  130.         }
  131.  
  132.         newCityNum = cityPointer;
  133.     }
  134.  
  135.     sprintf(groundTrkCity,"%s",city[cityPointer].cty);
  136.  
  137.     cityVec[0] = city[cityPointer].X;
  138.     cityVec[1] = city[cityPointer].Y;
  139.     cityVec[2] = city[cityPointer].Z;
  140.  
  141.     for (j = 0; j <= 2; j++)
  142.         distVec[j] = cityVec[j] - sspVec[j];
  143.  
  144.     arg = scalar(cityVec,sspVec);
  145.  
  146.     if (arg >  1.0) arg =  1.0;
  147.     if (arg < -1.0) arg = -1.0;
  148.  
  149.     alpha = acos(arg);
  150.  
  151.     *groundTrkDist = alpha * EARTHRADIUS;
  152.     *cityLtd       = city[cityPointer].lat * CRD;
  153.     *cityLng       = city[cityPointer].lng * CRD;
  154.  
  155.     cosLatSite  = cos(city[cityPointer].lat);
  156.     sinLatSite  = sin(city[cityPointer].lat);
  157.     cosLngSite  = cos(city[cityPointer].lng);
  158.     sinLngSite  = sin(city[cityPointer].lng);
  159.  
  160.     northVec[0] = -cosLngSite*sinLatSite;
  161.     northVec[1] = -sinLngSite*sinLatSite;
  162.     northVec[2] =  cosLatSite;
  163.  
  164.     cross(cityVec,northVec,eastVec,-1);
  165.  
  166.     aziX = scalar(northVec,distVec);
  167.     aziY = scalar(eastVec,distVec);
  168.  
  169.     if (aziX == 0.0)
  170.         azi = (aziY > 0.0) ? HALFPI : THREEHALFPI;
  171.     else
  172.         azi = PI - atan2(aziY,aziX);
  173.  
  174.     if (azi < 0.0)
  175.         azi += PI;
  176.  
  177.     azi *= CRD;
  178.  
  179.     dir  = (int) ((azi + 11.25) / 22.5) % 16;
  180.  
  181.     if (cityPointer == 0) dir = 8;                          /* the North Pole */
  182.     if (cityPointer == 1) dir = 0;                          /* the South Pole */
  183.  
  184.     sprintf(groundTrkDir,"%s",gndTrkVector[dir]);
  185.     return;
  186. }
  187.  
  188. /******************************************************************************/
  189. /*                                                                            */
  190. /* readCities: reads the city data base into a structure                      */
  191. /*                                                                            */
  192. /******************************************************************************/
  193.  
  194. void readCities()
  195.  
  196. {
  197.     double lat, lng, alt;
  198.     int    i;
  199.     char   cityDat[80], cityName[50], str[100];
  200.     FILE   *cityFile;
  201.  
  202.     if (verboseFlag)
  203.         printf("\nreading city data base ...\n");
  204.  
  205.     sprintf(cityDat,"%s/%s/%s",strpHome,DATA,CITIES);
  206.  
  207.     if ((cityFile = fopen(cityDat,"r")) == NULL)
  208.     {
  209.         printf("cannot open input file '%s'\n",cityDat);
  210.         exit(-1);
  211.     }
  212.  
  213.     numCities = 0;
  214.  
  215.     while (fgets(str,80,cityFile) && numCities < MAXCITIES)
  216.     {
  217.         sscanf(str,"`%[^`]`,%lf,%lf,%lf",cityName,&lat,&lng,&alt);
  218.  
  219.         city[numCities].lat = lat;
  220.         city[numCities].lng = lng;
  221.         city[numCities].alt = alt;
  222.  
  223.         if ((int) strlen(cityName) > MAXCITYLEN)
  224.         {
  225.             i = MAXCITYLEN;
  226.  
  227.             do
  228.             {
  229.                 i--;
  230.             }
  231.             while (cityName[i] != ' ');
  232.  
  233.             if (cityName[i-1] == ',')
  234.                 i--;
  235.  
  236.             cityName[i] = '\0';
  237.         }
  238.  
  239.         strcpy(city[numCities].cty,cityName);
  240.  
  241.         city[numCities].lat *= CDR;
  242.         city[numCities].lng *= CDR;
  243.  
  244.         numCities++;
  245.     }
  246.  
  247.     fclose(cityFile);
  248.  
  249.     if (verboseFlag)
  250.         printf("data base contains %d locations\n",numCities);
  251.  
  252.     return;
  253. }
  254.  
  255. /******************************************************************************/
  256. /*                                                                            */
  257. /* calcCityVectors: calculates city vectors for the nearest city display      */
  258. /*                  in the geodetic reference system                          */
  259. /*                                                                            */
  260. /******************************************************************************/
  261.  
  262. void calcCityVectors()
  263.  
  264. {
  265.     double cityCosLat, citySinLat, cityCosLng, citySinLng;
  266.     int    i;
  267.  
  268.     for (i = 0; i < numCities; i++)
  269.     {
  270.         cityCosLat = cos(city[i].lat);
  271.         citySinLat = sin(city[i].lat);
  272.         cityCosLng = cos(city[i].lng);
  273.         citySinLng = sin(city[i].lng);
  274.  
  275.         city[i].X  = cityCosLat * cityCosLng;
  276.         city[i].Y  = cityCosLat * citySinLng;
  277.         city[i].Z  = citySinLat;
  278.     }
  279.  
  280.     return;
  281. }
  282.  
  283. /******************************************************************************/
  284. /*                                                                            */
  285. /* getMaidenHead: calculates Maidenhead locator for geodetic coordinates      */
  286. /*                                                                            */
  287. /******************************************************************************/
  288.  
  289. void getMaidenHead(mLtd,mLng,mStr)
  290.  
  291. double mLtd, mLng;
  292. char   *mStr;
  293.  
  294. {
  295.     int i, j, k, l, m, n;
  296.  
  297.     mLng = reduce(180.0 - mLng * CRD + ONEPPM,0.0,360.0);
  298.     mLtd = reduce( 90.0 + mLtd * CRD + ONEPPM,0.0,360.0);
  299.  
  300.     i = (int) (mLng / 20.0);
  301.     j = (int) (mLtd / 10.0);
  302.  
  303.     mLng -= (double) i * 20.0;
  304.     mLtd -= (double) j * 10.0;
  305.  
  306.     k = (int) (mLng / 2.0);
  307.     l = (int) (mLtd / 1.0);
  308.  
  309.     mLng -= (double) k * 2.0;
  310.     mLtd -= (double) l * 1.0;
  311.  
  312.     m = (int) (mLng * 12.0);
  313.     n = (int) (mLtd * 24.0);
  314.  
  315.     sprintf(mStr,"%c%c%d%d%c%c",
  316.         'A' + (char) i, 'A' + (char) j, k, l, 'A' + (char) m, 'A' + (char) n);
  317.  
  318.     return;
  319. }
  320.  
  321. /******************************************************************************/
  322. /*                                                                            */
  323. /* getPosFromMaidenHead: calculates position from Maidenhead locator          */
  324. /*                                                                            */
  325. /******************************************************************************/
  326.  
  327. int getPosFromMaidenHead(mStr,mLtd,mLng)
  328.  
  329. char   *mStr;
  330. double *mLtd, *mLng;
  331.  
  332. {
  333.     int  error;
  334.  
  335.     upperCase(mStr);
  336.  
  337.     error = ((int) strlen(mStr) != 6) ? TRUE : FALSE;
  338.  
  339.     if (mStr[0] < 'A' || mStr[0] > 'R') error = TRUE;
  340.     if (mStr[1] < 'A' || mStr[1] > 'R') error = TRUE;
  341.     if (mStr[2] < '0' || mStr[2] > '9') error = TRUE;
  342.     if (mStr[3] < '0' || mStr[3] > '9') error = TRUE;
  343.     if (mStr[4] < 'A' || mStr[4] > 'X') error = TRUE;
  344.     if (mStr[5] < 'A' || mStr[5] > 'X') error = TRUE;
  345.  
  346.     *mLng = (double) (mStr[0] - 'A') * 20.0 + 
  347.             (double) (mStr[2] - '0') * 2.0 + 
  348.             (double) (mStr[4] - 'A') / 12.0 + 2.50 / 60.0;
  349.  
  350.     if (*mLng < 0.0 || *mLng > 360.050)
  351.         error = TRUE;
  352.  
  353.     *mLtd = (double) (mStr[1] - 'A') * 10.0 + 
  354.             (double) (mStr[3] - '0') * 1.0 + 
  355.             (double) (mStr[5] - 'A') / 24.0 + 1.25 / 60.0;
  356.  
  357.     if (*mLtd < 0.0 || *mLtd > 180.025)
  358.         error = TRUE;
  359.  
  360.     *mLng -= 180.0;
  361.     *mLng *=  -1.0;
  362.     *mLng *=   CDR;
  363.  
  364.     *mLtd -=  90.0;
  365.     *mLtd *=   CDR;
  366.  
  367.     if (error)
  368.     {
  369.         *mLng = 0.0;
  370.         *mLtd = 0.0;
  371.     }
  372.  
  373.     return(error);
  374. }
  375.  
  376. /******************************************************************************/
  377. /*                                                                            */
  378. /* End of function block satcity.c                                            */
  379. /*                                                                            */
  380. /******************************************************************************/
  381.